package cn.ltgodm.template.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.ltgodm.template.common.annotation.DataScope;
import cn.ltgodm.template.common.constant.Constants;
import cn.ltgodm.template.common.constant.UserConstants;
import cn.ltgodm.template.common.domain.entity.User;
import cn.ltgodm.template.common.domain.vo.DeptVO;
import cn.ltgodm.template.common.domain.vo.UserVO;
import cn.ltgodm.template.common.exception.ServiceException;
import cn.ltgodm.template.common.utils.SecurityUtils;
import cn.ltgodm.template.common.utils.SpringUtils;
import cn.ltgodm.template.common.utils.StringUtils;
import cn.ltgodm.template.user.domain.param.DeptParam;
import cn.ltgodm.template.user.domain.param.DeptQueryParam;
import cn.ltgodm.template.user.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ltgodm.template.common.domain.entity.Dept;
import cn.ltgodm.template.user.service.DeptService;
import cn.ltgodm.template.user.mapper.DeptMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * @author wenpeng
 * @description 针对表【lt_dept(部门表)】的数据库操作Service实现
 * @createDate 2024-03-17 22:12:11
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    @Resource
    private DeptMapper deptMapper;
    @Resource
    private UserMapper userMapper;

    /**
     * 分页获取部门信息
     *
     * @param deptQueryParam 部门查询参数
     * @return 部门信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public IPage<DeptVO> getDeptList(DeptQueryParam deptQueryParam) {
        LambdaQueryWrapper<Dept> lqw = getQueryWrapper(deptQueryParam);
        lqw.eq(Dept::getDelFlag, Constants.DEL_FLAG_NORMAL);
        IPage<Dept> page = new Page<>(deptQueryParam.getPageNum(), deptQueryParam.getPageSize());
        return deptMapper.selectDeptList(page, lqw, deptQueryParam.getParams());
    }

    @Override
    @DataScope(deptAlias = "d")
    public List<DeptVO> getDeptListExcludeChild(Long deptId) {
        LambdaQueryWrapper<Dept> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(Dept::getDelFlag, Constants.DEL_FLAG_NORMAL)
                .ne(Dept::getParentId, deptId)
                .notLike(Dept::getAncestors, deptId)
        ;
        IPage<Dept> page = new Page<>(1, -1);
        return deptMapper.selectDeptList(page, lqw, new HashMap<>()).getRecords();
    }

    /**
     * 根据部门编号获取详细信息
     *
     * @param deptId 部门编号
     * @return 部门信息
     */
    @Override
    public DeptVO getDeptById(Long deptId) {
        return deptMapper.selectDeptById(deptId);
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param deptParam 部门参数
     * @return 返回是否唯一
     */
    @Override
    public boolean checkDeptNameUnique(DeptParam deptParam) {
        Long deptId = ObjectUtil.isNull(deptParam.getDeptId()) ? -1L : deptParam.getDeptId();
        Dept dept = deptMapper.checkDeptNameUnique(deptParam.getDeptName(), deptParam.getParentId());
        if (ObjectUtil.isNotNull(dept) && deptId.compareTo(dept.getDeptId()) != 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增部门
     *
     * @param deptParam 部门参数
     * @return 返回是否成功
     */
    @Override
    public int insertDept(DeptParam deptParam) {
        DeptVO parent = deptMapper.selectDeptById(deptParam.getParentId());
        if (!UserConstants.DEPT_NORMAL.equals(parent.getStatus())) {
            // 如果父节点不为正常状态,则不允许新增子节点
            throw new ServiceException("部门停用，不允许新增");
        }
        deptParam.setCreateBy(SecurityUtils.getUsername());
        deptParam.setAncestors(parent.getAncestors() + "," + deptParam.getParentId());
        return deptMapper.insert(deptParam);
    }

    /**
     * 校验用户获取数据权限
     *
     * @param deptId 部门编号
     */
    @Override
    public void checkDeptDataScope(Long deptId) {
        if (!UserVO.isAdmin(SecurityUtils.getUserId())) {
            DeptQueryParam deptQueryParam = new DeptQueryParam();
            deptQueryParam.setPageSize(-1);
            deptQueryParam.setDeptId(deptId);
            IPage<DeptVO> iPage = SpringUtils.getAopProxy(this).getDeptList(deptQueryParam);
            if (ObjectUtil.isNull(iPage) || CollectionUtil.isEmpty(iPage.getRecords())) {
                throw new ServiceException("没有权限访问部门数据！");
            }
        }

    }

    /**
     * 查询正常子部门数目
     *
     * @param deptId 部门编号
     * @return 子部门数目
     */
    @Override
    public int selectNormalChildrenDeptById(Long deptId) {
        LambdaQueryWrapper<Dept> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dept::getParentId, deptId)
                .eq(Dept::getStatus, UserConstants.DEPT_NORMAL)
                .eq(Dept::getDelFlag, Constants.DEL_FLAG_NORMAL);
        return deptMapper.selectCount(lqw).intValue();
    }

    /**
     * 修改部门
     *
     * @param deptParam 部门参数
     * @return 返回受影响行数
     */
    @Override
    @Transactional
    public int updateDept(DeptParam deptParam) {
        DeptVO newParent = deptMapper.selectDeptById(deptParam.getParentId());
        DeptVO oldDept = deptMapper.selectDeptById(deptParam.getDeptId());
        String newAncestors = newParent.getAncestors() + "," + newParent.getDeptId();
        //修改所有子部门的祖级列表
        if (ObjectUtil.isNotNull(newParent) && ObjectUtil.isNotNull(oldDept)) {
            String oldAncestors = oldDept.getAncestors();
            updateDeptChildren(deptParam.getDeptId(), newAncestors, oldAncestors);
        }
        deptParam.setUpdateBy(SecurityUtils.getUsername());
        deptParam.setAncestors(newAncestors);
        deptParam.setCreateBy(null);
        int row = deptMapper.updateById(deptParam);
        if (UserConstants.DEPT_NORMAL.equals(deptParam.getStatus()) &&
                StringUtils.isNotEmpty(deptParam.getAncestors()) &&
                !StringUtils.equals("0", deptParam.getAncestors()))
        {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatusNormal(deptParam);
        }
        return row;
    }


    /**
     * 是否存在子部门
     * @param deptId 部门编号
     * @return 返回存在结果
     */
    @Override
    public boolean hasChildByDeptId(Long deptId) {
        LambdaQueryWrapper<Dept> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dept::getParentId, deptId).eq(Dept::getDelFlag, Constants.DEL_FLAG_NORMAL);
        return deptMapper.selectCount(lqw).intValue() > 0;
    }

    /**
     * 部门是否存在用户
     * @param deptId 部门编号
     * @return 返回存在结果
     */
    @Override
    public boolean checkDeptExistUser(Long deptId) {
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getDeptId, deptId).eq(User::getDelFlag, Constants.DEL_FLAG_NORMAL);
        return userMapper.selectCount(lqw).intValue() > 0;
    }


    /**
     * 删除部门
     * @param deptId 部门编号
     * @return 返回受影响行数
     */
    @Override
    public int deleteDeptById(Long deptId) {
        return deptMapper.deleteById(deptId);
    }


    /**
     * 修改该部门的父级部门状态
     * @param deptParam 部门信息
     */
    private void updateParentDeptStatusNormal(DeptParam deptParam) {
        List<String> idList = Arrays.asList(deptParam.getAncestors().split(","));
        updateDeptStatusNormal(idList);
    }

    /**
     * 修改部门状态为正常
     * @param idList 部门id集合
     */
    private void updateDeptStatusNormal(List<String> idList) {
        LambdaQueryWrapper<Dept> lqw = new LambdaQueryWrapper<>();
        lqw.in(Dept::getDeptId,idList);
        Dept dept = new Dept();
        dept.setStatus(UserConstants.DEPT_NORMAL);
        deptMapper.update(dept,lqw);
    }

    /**
     * 修改子元素关系
     *
     * @param deptId        部门编号
     * @param newAncestors  新的祖级列表
     * @param oldAncestors  旧的祖级列表
     */
    private void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        List<DeptVO> children = deptMapper.selectChildrenDeptById(deptId);
        List<Dept> deptList = new ArrayList<>();
        for (DeptVO child : children) {
            Dept dept = new Dept();
            dept.setDeptId(child.getDeptId());
            dept.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
            deptList.add(dept);
        }
        if (ObjectUtil.isNotEmpty(deptList)) {
            this.updateBatchById(deptList);
        }
    }


    /**
     * 获取查询条件
     *
     * @param deptQueryParam 部门查询参数
     * @return 查询条件
     */
    private LambdaQueryWrapper<Dept> getQueryWrapper(DeptQueryParam deptQueryParam) {
        LambdaQueryWrapper<Dept> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(ObjectUtil.isNotNull(deptQueryParam.getDeptId()), Dept::getDeptId, deptQueryParam.getDeptId())
                .eq(ObjectUtil.isNotNull(deptQueryParam.getParentId()), Dept::getParentId, deptQueryParam.getParentId())
                .eq(StringUtils.isNotBlank(deptQueryParam.getDeptName()), Dept::getDeptName, deptQueryParam.getDeptName())
                .eq(StringUtils.isNotBlank(deptQueryParam.getStatus()), Dept::getStatus, deptQueryParam.getStatus())
                .eq(StringUtils.isNotBlank(deptQueryParam.getLeader()), Dept::getLeader, deptQueryParam.getLeader())
        ;
        return lqw;
    }



}




